# -*- coding:utf-8 -*-
from django.shortcuts import render
from django.http import HttpResponse,StreamingHttpResponse,HttpResponseRedirect
import json
import os
import uuid
import hashlib
import re
from wsgiref.util import FileWrapper
import mimetypes

from MVonline1.settings import HOST,BASE_DIR
from app1 import encrypt
from MVonline1.settings import FILE_PATH
from . import utils, take_a_image
from .models import *



# Create your views here.

def index(req):  # 重定向到主页
    # cxt = {'mess': 'Oh my god! '}
    # return render(req, 'index.html', cxt)
    return HttpResponseRedirect("/static/index.html")

def favicon(req):
    path =  BASE_DIR + '/static' + req.path_info 
    if(os.path.exists(path)):
        content_type, encoding = mimetypes.guess_type(path)
        resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
        resp['Cache-Control']="max-age=8640"
    else:
        resp = HttpResponse("找不到favicon.ico", status=404)
    return resp


# 注册
def log_up(req):
    if req.method=='POST':
        user=json.loads(req.body.decode())
        u = User.objects.filter(username=user.get('username')).first()
        if u:  # 用户已经存在
            res={'userID': ''}
            return HttpResponse(json.dumps(res))
        else:
            username=user.get("username")
            password=user.get('password')
            password = utils._getMD5(password)
            print(username, password)
            tmp = User.objects.create(username=username, password=password, vip_id=1)
            md5=utils.create_token(tmp)
            res={'userID': md5}
            return HttpResponse(json.dumps(res))
    return HttpResponse('')
                

# 登陆
def log_in(req):
    if req.method == 'POST':
        data = json.loads(req.body.decode())
        username=data.get("username")
        password=data.get('password')
        password = encrypt.my_decrypt(password)
        password = utils._getMD5(password)  # 加密密码
        if username and password:
            user = User.objects.filter(username=username,
                password=password).first()
            if user and user.admin != -1:
                print(user)
                md5 = utils.create_token(user)
                res={'userID': md5}
                return HttpResponse(json.dumps(res))
    return HttpResponse('')

# 注销登陆
def log_out(req):
    user = getattr(req, 'user')
    Token.objects.filter(user=user).delete()
    res={'result':'ok'}
    return HttpResponse(json.dumps(res))

# 返回用户信息
def get_user(req):
    user = getattr(req, 'user')
    print('get_user', user)
    vip = user.vip
    cxt={'uid': user.id,
        'username': user.username,
        'grade': vip.grade, 
        'size':vip.size,
        'usedsize': utils.get_usedsize(user),
        'level': user.admin  # 管理员等级。0是普通用户
    }
    return HttpResponse(json.dumps(cxt))

# 修改密码
def change_pwd(req):
    if req.method=='POST':
        data=json.loads(req.body.decode())
        user = getattr(req, 'user')
        Token.objects.get(user=user).delete()
        user.password= utils._getMD5(data['password']) 
        user.save()
        md5 = utils.create_token(user)
        cxt={'userID': md5}
        return HttpResponse(json.dumps(cxt))
    return HttpResponse('')

# 用户销号或者超级管理员删除用户
def delete_user(req):
    user = getattr(req,'user')
    uid = req.GET.get('uid')
    if not uid:
        _delete_user(user)
    else:
        theUser=User.objects.get(id=uid)
        _delete_user(theUser)
    
def _delete_user(user):
    try:
        token = Token.objects.get(user=user)
    except:
        token=None
    if token:
        token.delete()
    resLists = ResList.objects.filter(user=user).all()
    for resList in resLists:
        utils.delete_res(resList)
    user.delete()
    cxt={'result':'ok'}
    return HttpResponse(json.dumps(cxt))

# 上传文件
def upload_file(req):
    if req.method =='POST':
        myFile=req.FILES.get('myfile', None)
        userID = req.POST.get('userID', None)
        fileType=req.POST.get('type', None)
        user = utils.check_token(userID)
        print('post upload', userID)
        if user and myFile:
            extension = myFile.name.split('.')[-1] 
            size = myFile.size
            filename=uuid.uuid4().hex + '.'+ extension
            path = os.path.join(FILE_PATH, filename)
            m = hashlib.md5()
            with open(path,'wb') as f:
                for chunk in myFile.chunks():
                    f.write(chunk)
                    m.update(chunk)
            md5 = m.hexdigest()
            print("file md5: ", md5)
            res = Resources.objects.filter(md5=md5).first()
            if (res):
                print('res exist')
                if not ResList.objects.filter(res=res,user=user).first():#若未引用
                    if( not utils.check_size(user, size)):
                        ctx={'mess':'空间不足，上传失败'}
                        print("空间不足，上传失败")
                        utils._delete_file(filename)
                        return HttpResponse(json.dumps(ctx))
                    ResList.objects.create(user=user,res=res,filename=myFile.name.split('.')[-2])
                    res.num += 1
                    res.save()
                utils._delete_file(filename)
            else:
                print('new Resources')  # 首次创建并且引用
                if( not utils.check_size(user, size)):
                    ctx={'mess':'空间不足，上传失败'}
                    print("空间不足，上传失败")
                    utils._delete_file(filename)
                    return HttpResponse(json.dumps(ctx))
                res = Resources.objects.create(md5=md5,realPath=filename,filetype=fileType,
                        fileSize=size)
                ResList.objects.create(user=user,res=res,filename=myFile.name.split('.')[-2])
            ctx={'mess':'ok'}
            return HttpResponse(json.dumps(ctx))
        ctx={'mess':'上传失败'}
        return HttpResponse(json.dumps(ctx))
    else:
        userID = req.GET.get('userID')
        user = utils.check_token(userID)
        if(user):
            cxt={'mess':'', 'userID': userID,'myhost': HOST}
        else:
            cxt={'mess':'还未登陆', 'userID': userID, 'myhost': HOST}
        return render(req,'upload.html',cxt)

# 获取文件列表
def get_list(req):
    user = getattr(req, 'user')
    resList = ResList.objects.filter(user=user)
    myList=[]
    for l in resList:
        res=l.res
        line={'filename':l.filename, 
        'size':res.fileSize, 'uploadTime':res.uploadTime,
        'filetype':res.filetype, 
        'listID':l.id}
        myList.append(line)
    ctx={'result':'ok', 'list':myList}
    return HttpResponse(json.dumps(ctx,cls=utils.CJsonEncoder))

# 删除文件
def delete_file(req):
    if req.method=='POST':
        data = json.loads(req.body.decode())
        if data:
            user = getattr(req, 'user')
            if  data.get('listID'):
                resList=ResList.objects.filter(id=data.get('listID'),user=user).first()
                if resList:
                    utils.delete_res(resList)
                    ctx={'result':True}
                    return HttpResponse(json.dumps(ctx))
    return HttpResponse('')

# 重命名
def rename_file(req):
    if req.method=='POST':
        data=json.loads(req.body.decode())
        if data  and data.get('listID') and data.get('filename'):
            user=getattr(req, 'user')
            resList=ResList.objects.filter(id=data.get('listID'),user=user).first()
            if resList:
                resList.filename=data.get('filename')
                resList.save()
                ctx={'result': True}
                return HttpResponse(json.dumps(ctx))
    return HttpResponse('')
# 视频生成器
def _file_iterator(file_name,chunk_size=8192,offset=0,length=None):
    with open(file_name, 'rb') as f:
        f.seek(offset, os.SEEK_SET)
        remaining = length
        while True:
            # min 是保证读文件不越界
            bytes_length=chunk_size if remaining is None else min(remaining,chunk_size)
            data=f.read(bytes_length)
            if not data:
                break
            if remaining:
                remaining -= len(data)
            yield data
# 返回视频流
def _stream_video(request, path):
    """将视频文件以流媒体的方式响应"""
    range_header = request.META.get('HTTP_RANGE', '').strip()
    range_re = re.compile(r'bytes\s*=\s*(\d+)\s*-\s*(\d*)', re.I)  # 形如 bytes 起始值-终止值
    range_match = range_re.match(range_header)
    size = os.path.getsize(path)
    content_type, encoding = mimetypes.guess_type(path)
    content_type = content_type or 'application/octet-stream'
    if range_match:
        first_byte, last_byte = range_match.groups()
        first_byte = int(first_byte) if first_byte else 0
        last_byte = first_byte + 1024 * 1024 * 8    # 8M 每片,响应体最大体积
        if last_byte >= size:
            last_byte = size - 1  #  最后一个字节
        length = last_byte - first_byte + 1
        resp = StreamingHttpResponse(_file_iterator(path, offset=first_byte, length=length), 
                                    status=206, # 206 Partial Content 客户发送了一个带有Range头的get请求，服务器完成了它（http 1.1新）
                                    content_type=content_type )
        resp['Content-Length'] = str(length)
        resp['Content-Range'] = 'bytes %s-%s/%s' % (first_byte, last_byte, size)
    else:
        # 不是以视频流方式的获取时，以生成器方式返回整个文件，节省内存
        resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
        resp['Content-Length'] = str(size)
    resp['Accept-Ranges'] = 'bytes'
    resp['Content-Disposition']="attachment;filename="+path.split('/')[-1]
    return resp

# 获取文件数据
def get_file_data(req):
    listID=req.GET.get('listID')
    userID=req.GET.get('userID')
    print(userID, listID)
    if listID and userID :
        user = utils.check_token( userID )
        resList=ResList.objects.filter(id= listID , user=user).first()
        if resList:
            filename = resList.res.realPath
            path = os.path.join(FILE_PATH, filename)
            return _stream_video(req, path)
    return HttpResponse("")

# 获取视频封面
def get_image(req):
    userID=req.GET.get('userID')
    listID=req.GET.get('listID')
    print(userID, listID)
    if userID and  listID:
        user=utils.check_token( userID )
        if user : 
            resList=ResList.objects.filter(id= listID ,user=user).first()
            if resList:
                filename=resList.res.realPath
                path = os.path.join(FILE_PATH, filename)
                imgPath = path + ".jpg"
                if not os.path.exists(imgPath):
                    # 否则生成封面
                    try:
                        take_a_image.get_frame_from_video(path, 2000, imgPath) # 取 2000 ms
                    except Exception as e:
                        try:
                            take_a_image.get_frame_from_video(path, 500, imgPath)
                        except Exception as ex:
                            resp = HttpResponse("", status=404)
                            return resp

                content_type, encoding  = mimetypes.guess_type(imgPath)
                resp = StreamingHttpResponse(
                    FileWrapper(open(imgPath, 'rb')), 
                    content_type=content_type)
                resp['Cache-Control']="max-age=8640"
                return resp
    return HttpResponse('')




# 返回静态文件
def static(req):
    path =  BASE_DIR + req.path_info 
    print('MY STATIC', path)
    if(os.path.exists(path)):
        content_type, encoding = mimetypes.guess_type(path)
        resp = StreamingHttpResponse(FileWrapper(open(path, 'rb')), content_type=content_type)
        resp['Cache-Control']="max-age=8640000"
    else:
        resp = HttpResponse("", status=404)
    return resp


# 管理员相关，1 提拔和打压管理员
# POST:{uid, level} 
def make_admin(req):
    if req.method == "POST": #设置admin级别
        user = getattr(req, 'user')
        admin_grade = user.admin
        if admin_grade >0: 
            data = json.loads(req.body.decode())
            uid = data.get('uid')
            level = int(data.get("level"))
            theUser=User.objects.get(id=uid)
            if theUser:
                theUser.admin = level
                theUser.save()
                return HttpResponse("succ")
    return HttpResponse("")

# 管理员获取所有用户
def get_all_user(req):
    if req.method == "GET":
        user = getattr(req, 'user')
        admin_grade = user.admin
        if admin_grade == 15:
            users = User.objects.filter(admin__lt=15)
        else:
            users = User.objects.filter(admin__lt=1)
        userList=  []
        for eachUser in users:
            userList.append({
                'uid': eachUser.id,
                'username': eachUser.username,
                'level': eachUser.admin,
                'grade': eachUser.vip.grade,
                'size': eachUser.vip.size,
                'usedsize': utils.get_usedsize(eachUser),
            })
        return HttpResponse(json.dumps(userList))
    return HttpResponse("")

# 修改用户VIP
# POST：{uid , vip}
def vip_user(req):
    if req.method == "POST":
        user = getattr(req, 'user')
        if user.admin > 0:
            data = json.loads(req.body.decode())
            theUser = User.objects.get(id=data.get('uid'))
            if theUser:
                theUser.vip_id = data.get('vip')
                theUser.save()
                return HttpResponse("SUCC")
    return HttpResponse("")


                






